/*
 * OREKIT-X
 * Copyright 2002-2008 CS Communication & Systemes
 * 
 * Parts of this software package have been licensed to CS
 * Communication & Systemes (CS) under one or more contributor license
 * agreements.  See the NOTICE file distributed with this work for
 * additional information.
 *  
 * This is an experimental copy of OREKIT from www.orekit.org.
 * Please use the original OREKIT from orekit.org for normal work
 * unrelated to this research project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You
 * may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package ore.propagation.events;

import ore.SpacecraftState;
import ore.errors.OrekitException;


/** 
 * Space dynamics event detection functions inform and direct stepwise
 * propagation and integration in the modeling of scenarios.
 *
 * Event detectors are a useful solution to meet the requirements of
 * propagators for discrete conditions.  The state of each event
 * detector is queried by the integrator at each step.  When the sign
 * of the underlying "g" switching function changes, the step is
 * rejected and reduced, in order to make sure the sign changes occur
 * only at steps' boundaries.
 *
 * When step ends exactly at a switching function sign change, the
 * corresponding event is triggered, by calling the "eventOccurred"
 * method. The method can do whatever it needs with the event (logging
 * it, performing some processing, ignore it ...).
 * 
 * The return value of the "eventOccurred" method will be used by the
 * propagator to stop or resume propagation, possibly changing the
 * state vector.
 * 
 * This class reflects the {@link
 * org.apache.commons.math.ode.EventHandler}, adapted to with this
 * package.
 *
 * @author Luc Maisonobe
 * @author V&eacute;ronique Pommier-Maurussane
 */
public interface EventDetector
    extends java.io.Serializable
{
    /** 
     * This value should be used as the return value of the {@link
     * #eventOccurred eventOccurred} method when the propagation
     * should be stopped after the event ending the current step.
     */
    public final static int STOP = 0;
    /** 
     * Reset state indicator.
     * 
     * This value should be used as the return value of the {@link
     * #eventOccurred eventOccurred} method when the propagation
     * should go on after the event ending the current step, with a
     * new state (which will be retrieved thanks to the {@link
     * #resetState resetState} method).
     */
    public final static int RESET_STATE = 1;
    /** 
     * Reset derivatives indicator.
     * 
     * This value should be used as the return value of the {@link
     * #eventOccurred eventOccurred} method when the propagation
     * should go on after the event ending the current step, with
     * recomputed derivatives vector.
     */
    public final static int RESET_DERIVATIVES = 2;
    /** 
     * This value should be used as the return value of the {@link
     * #eventOccurred eventOccurred} method when the propagation
     * should go on after the event ending the current step.
     */
    public final static int CONTINUE = 3;

    /** 
     * Compute the value of the switching function.
     * 
     * This function must be continuous (at least in its roots
     * neighborhood), as the integrator will need to find its roots to
     * locate the events.
     * 
     * @param s The current state information: date, kinematics, attitude
     * 
     * @return Value of the switching function
     * 
     * @exception OrekitException Some specific error 
     */
    public double g(SpacecraftState s) throws OrekitException;

    /** 
     * Handle an event and choose what to do next.
     * 
     * @param s The current state information : date, kinematics, attitude
     * 
     * @param increasing If true, the value of the switching function
     * increases when times increases around event (note that increase
     * is measured with respect to physical time, not with respect to
     * propagation which may go backward in time)
     * 
     * @return One of {@link #STOP}, {@link #RESET_STATE}, {@link
     * #RESET_DERIVATIVES} or {@link #CONTINUE}
     * 
     * @exception OrekitException Some specific error
     */
    public int eventOccurred(SpacecraftState s, boolean increasing) throws OrekitException;

    /** 
     * Reset the state prior to continue propagation.
     * 
     * This method is called after the step handler has returned and
     * before the next step is started, but only when {@link
     * #eventOccurred} has itself returned the {@link #RESET_STATE}
     * indicator. It allows the user to reset the state for the next
     * step, without perturbing the step handler of the finishing
     * step. If the {@link #eventOccurred} never returns the {@link
     * #RESET_STATE} indicator, this function will never be called,
     * and it is safe to simply return null.
     * 
     * @param oldState Old state
     * 
     * @return New state
     * 
     * @exception OrekitException State cannot be reset
     */
    public SpacecraftState resetState(SpacecraftState oldState) throws OrekitException;
    /** 
     * @return The convergence threshold in the event time search.
     */
    public double getThreshold();
    /** 
     * @return Maximal time interval between switching function checks
     */
    public double getMaxCheckInterval();
    /** 
     * @return Maximal number of iterations in the event time search
     */
    public int getMaxIterationCount();

}
